package cn.gailvlun.gll.net.interceptor;

import android.os.Build;

import com.blankj.utilcode.util.EncodeUtils;

import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

import cn.gailvlun.gll.event.AuthEvent;
import cn.gailvlun.gll.net.HttpMethods;
import cn.gailvlun.gll.net.base.Profile;
import cn.gailvlun.gll.net.base.RefreshTokenReq;
import cn.gailvlun.gll.net.base.RefreshTokenRes;
import cn.gailvlun.gll.net.token.CustomUtils;
import cn.gailvlun.gll.util.IsEmpty;
import cn.gailvlun.gll.util.LogUtil;
import cn.gailvlun.gll.util.ProfileUtil;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;



public class TokenInterceptor implements Interceptor {

    private Map<Integer, String> mAutoInfos;

    public TokenInterceptor(Map<Integer, String> autoInfos) {
        mAutoInfos = autoInfos;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Integer orderKey = CustomUtils.authInfo(request);
        if (mAutoInfos.containsKey(orderKey)) {
            
            if (ProfileUtil.isTokenExpired()) {
                
                LogUtil.d("beforeLock, time: " + System.currentTimeMillis() + ", chain: " + chain);
                synchronized (HttpMethods.class) {
                    if (ProfileUtil.isTokenExpired()) {
                        LogUtil.d("beforeRefreshToken, time: " + System.currentTimeMillis() + ", chain: " + chain);
                        if (!syncRefreshToken()) {
                            LogUtil.d("invalid, time: " + System.currentTimeMillis() + ", chain: " + chain);
                            
                            return null;
                        }
                        try {
                            Thread.sleep(50);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
                LogUtil.d("afterLock, time: " + System.currentTimeMillis() + ", chain: " + chain);
            }

            String dbToken = ProfileUtil.getToken();
            String token = "JWT " + dbToken;
            if (!IsEmpty.string(token)) {
                request = chain
                        .request()
                        .newBuilder()
                        .addHeader("Authorization", token)
                        .build();
                return chain.proceed(request);
            }
        }
        request = chain.request().newBuilder().build();
        return chain.proceed(request);
    }

    
    private boolean syncRefreshToken() {
        Profile profile = ProfileUtil.getProfile();
        String clientId = profile.getUid() == null ? "+" + profile.getCountry_code() + profile.getMobile()
                : profile.getUid();
        try {
            retrofit2.Response<RefreshTokenRes> res = HttpMethods.getBaseService()
                    .refreshTokenSync(new RefreshTokenReq(clientId, profile.getRefresh_token()))
                    .execute();
            if (res.code() == 200) {
                RefreshTokenRes refreshTokenRes = res.body();
                ProfileUtil.refresh(refreshTokenRes);
            } else {
                EventBus.getDefault().post(new AuthEvent());
                return false;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
}
